<HTML><HEAD>
<!--
    --------------
    RPN Calculator
    --------------
-->

<SCRIPT LANGUAGE="JavaScript"><!-- hide from old browsers

/*
    THE JAVASCRIPT COOKBOOK by Erica Sadun, webrx@mindspring.com
    Copyright (c)1998 by Charles River Media.  All Rights Reserved.
    
    This applet can only be re-used or modifed by license holders of the
    JavaScript Cookbook CD-ROM.  Credit must be given in the source
    code and this copyright notice must be maintained. If you do
    not hold a license to the JavaScript Cookbook, you may NOT
    duplicate or modify this code for your own use.

    Use at your own risk. No warranty is given or implied of the suitability 
    of this applet for any specific application. Neither Erica Sadun nor 
    Charles River Media will be held responsible for any unwanted effects 
    due to the use of this applet or any derivative. 
*/

// Create an Array
function createArray(n)
{
    this.length = n;
    for (var i = 0; i < n; i++) {this[i] = 0}
    return this
}

// Initialize Global Variables
stack = createArray(20) // 20 should be big enough
sktop = 0               // Top of the Stack
entry = "0"             // Current Entry
restart = true          // Number: overwrite (restart) or add (!restart)

// Show the Stack
function showstack(aform)
{
    var answer=""
    for (var i = 0; i < sktop; i++) answer = stack[i] + ": " + answer
    aform.stack.value = answer
}


// Handle a Number Tap
function tap(aform, c)
{
    if (restart) // Either new start or stack just pushed
    {
        aform.answer.value = c
        restart = false
    }
    else if (c == '.') // Add decimal only if unique
    {
        if (aform.answer.value.indexOf(".") < 0)
            aform.answer.value += "."
    } else if (aform.answer.value == '0') // Zero gets overwritten
    {
        aform.answer.value = c 
    }
    else aform.answer.value += c // Add digit
}

// Clear the Current Entry
function clear(aform)
{
    aform.answer.value = '0'
    restart = true
}

// Handle a Math Request
function req(aform, afunction)
{
    if (sktop == 0) // push new value and function
    {
        // allow unary operations, default to (0 op Number)
        entry = eval("0" + afunction + aform.answer.value)
        
        // update the answer and prepare for new number or "enter"
        aform.answer.value = entry
        restart = true
        showstack(aform)
    }
    else // pop and evaluate
    {
        var v = stack[sktop-1] // pop stack
        sktop-- 
        
        // derive new answer
        var answer = eval(v + afunction + aform.answer.value)
        
        // display it
        aform.answer.value = "" + answer
        
        // reset for a new number and show stack
        entry =""
        restart = true
        showstack(aform)
    }
}

// Press the All Clear button
function ac(aform)
{
    // all clear
    aform.answer.value = "0"  // reset answer line
    restart = true            // prepare for a new number
    entry = ""
    sktop = 0                 // reset stack
    showstack(aform)          // show empty stack
}

// Push the Stack
function push(aform)
{
    
    stack[sktop] = ""+aform.answer.value // push onto stack
    sktop++                  // increase top of stack
    restart = true           // prepare for new number
    entry = ""
    aform.answer.value = "0" // reset input line
    showstack(aform)         // show stack
}

<!-- done hiding --></SCRIPT></HEAD>

<BODY bgcolor="ffffff" link="0000ff" vlink="770077">

<FONT COLOR="007777"><H1><IMG SRC="../GRAFX/UTENS.JPG" WIDTH=80 HEIGHT=50
ALIGN = CENTER>RPN Calculator</H1></FONT>

<BLOCKQUOTE>

    <FONT COLOR="770000">
    Try out this reverse polish notation calculator. It works like
    some popular scientific calculators.  Instead of tapping 5 + 3,
    you tap "5", "Enter", "3", "+".  Try these:<ul></FONT>
    <li> <b>Approximate PI</b>: tap "2", tap "2", tap "Enter", tap "7" and tap "/"
        <br><tt><FONT SIZE=2>[Postfix: 22 7 /]</FONT></tt>
    <li> <b>Calculate (5+3)/(4-2)</b>: tap "5", tap "Enter", tap "3", tap "+", 
        tap "Enter", tap "4", tap "Enter", tap "2", tap "-", tap "/".
        <br><tt><FONT SIZE=2>[Postfix: 5 3 + 4 2 - /]</FONT></tt>
    </ul>
    
</BLOCKQUOTE>

<BR><BR>

<CENTER><FORM><TABLE BORDER=1>
    
    <TR>
    <TD align=center  colspan=4><input type="text" name="stack" value="0" 
    size=23>: STACK</TD>
    </TR>
    
    <TR>
    <TD align=center  colspan=4><input type="text" name="answer" value="0" size=30></TD>
    </TR>
    
    <TR>
    <TD align=center ><input type="button" value="  7  " onClick="tap(this.form,'7')"></TD>
    <TD align=center ><input type="button" value="  8  " onClick="tap(this.form,'8')"></TD>
    <TD align=center ><input type="button" value="  9  " onClick="tap(this.form,'9')"></TD>
    <TD align=center ><input type="button" value="   /  " onClick="req(this.form,' / ')"></TD>
    </TR>
    
    <TR>
    <TD align=center ><input type="button" value="  4  " onClick="tap(this.form,'4')"></TD>
    <TD align=center ><input type="button" value="  5  " onClick="tap(this.form,'5')"></TD>
    <TD align=center ><input type="button" value="  6  " onClick="tap(this.form,'6')"></TD>
    <TD align=center ><input type="button" value="  *  " onClick="req(this.form,' * ')"></TD>
    </TR>

    <TR>
    <TD align=center ><input type="button" value="  1  " onClick="tap(this.form,'1')"></TD>
    <TD align=center ><input type="button" value="  2  " onClick="tap(this.form,'2')"></TD>
    <TD align=center ><input type="button" value="  3  " onClick="tap(this.form,'3')"></TD>
    <TD align=center ><input type="button" value="   -  " onClick="req(this.form,' - ')"></TD>
    </TR>
    
    <TR>
    <TD align=center ><input type="button" value="  C  " onClick="clear(this.form)"></TD>
    <TD align=center ><input type="button" value="  0  " onClick="tap(this.form,'0')"></TD>
    <TD align=center ><input type="button" value="  .  " onClick="tap(this.form,'.')"></TD>
    <TD align=center ><input type="button" value="  +  " onClick="req(this.form, ' + ')"></TD>
    </TR>
    
    <TR>
    <TD align=center  colspan=3 align=right>
    <input type="button" value="         Enter         "
        onClick="push(this.form)"></TD>
    <TD align=center ><input type="button" value=" AC " onClick="ac(this.form)"></TD>
    </TR> 
    
</TABLE></FORM></CENTER>

<BR><BR>

<FONT COLOR="007777"><H2>Discussion</H2></FONT>
<FONT SIZE=4>
    Unlike the previous calculator example, this RPN calculator 
    stores arguments in a stack. Operators are entered in postfix order 
    using reverse polish notation. Each operation pops the stack by
    one.  The results are shown in the answer line and must be manually
    pushed back onto the stack with the "Enter" key.  A simple array
    called <FONT COLOR="770000">stack</FONT> holds the stack data.
    The variable <FONT COLOR="770000">sktop</FONT> points to the 
    top of the stack.  The function below demonstrates a stack push.
    After each push, the answer line is reset to zero and the stack
    line is updated.
</FONT>

<FONT COLOR="770000"><PRE>
function push(aform)
{
    // push onto stack
    stack[sktop] = ""+aform.answer.value
    
    // increase the top of the stack
    sktop++
    
    // reset the answer to zero
    aform.answer.value = "0"
    
    // show the new stack
    showstack(aform)
    
    // reset for entering a new number
    restart = true
    entry = ""
}
</PRE></FONT>

<h5>Copyright &copy;1996 by Charles River Media, All Rights Reserved</h5>
</BODY>
</HTML>